package com.sunfeng.netty.heima.day01.select;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

@Slf4j
public class ChannelDemo6 {
    public static void main(String[] args) {
        try (ServerSocketChannel channel = ServerSocketChannel.open()) {
            channel.bind(new InetSocketAddress(8080));
            System.out.println(channel);
            Selector selector = Selector.open();
            channel.configureBlocking(false);
            channel.register(selector, SelectionKey.OP_ACCEPT);

            while (true) {
                int count = selector.select();
//                int count = selector.selectNow();
                 log.debug("select count: {}", count);
//                if(count <= 0) {
//                    continue;
//                }

                // 获取所有事件的 迭代器
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                log.debug("SelectionKey count: {}", selector.selectedKeys().size());
                while (iterator.hasNext()) {
                    // selectionKey
                    SelectionKey selectionKey = iterator.next();
                    // 判断链接类型
                    if (selectionKey.isAcceptable()) {
                        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
                        // 获取到socketChannel   必须进行处理   要不然后续操作获取不到
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        // 设置非阻塞
                        socketChannel.configureBlocking(false);
                        // 刚才测试忘记了加上这句
                        socketChannel.register(selector,SelectionKey.OP_READ);

                        log.debug("连接成功！！，{}", socketChannel);
                    }else if(selectionKey.isReadable()){
                        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
                        ByteBuffer allocate = ByteBuffer.allocate(120);
                        int read = socketChannel.read(allocate);
                        if(-1==read){
                            // cancel 会取消注册在 selector 上的 channel，并从 keys 集合中删除 key 后续不会再监听事件
                            selectionKey.channel();
                            socketChannel.close();
                        }else{
                            allocate.flip();
                            System.out.println(allocate);
                        }
                    }
                    //必须要移除
                    iterator.remove();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
